﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;
using System.Windows.Interactivity;

namespace ScrumBoard.Views
{
  public partial class Board : Page
  {
    public Board()
    {
      InitializeComponent();
      timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };

      if (WpfUtils.IsDesignMode) return;
      timer.Tick += (o, e) =>
      {
        fixDataGridRowsHeight();
        timer.Stop();
      };
    }

    // Executes when the user navigates to this page.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

    private void Story_ChildrenGenerating(object sender, ChildrenGeneratorEventArgs e)
    {
      var story = (StoryVM)e.Panel.DataContext;
      var taskState = (TaskState)CellToTaskStateConverer.Instance.Convert(e.Panel.VisualParent<DataGridCell>(), null, null, null);

      e.Items = story.Tasks
        .Where(t => t.State == taskState)
        .OrderBy(t => t.OrderNumber)
        .ToArray();
    }


    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
      foreach (var c in datagrid.Descendants<DataGridColumnHeadersPresenter>().First().GetVisualChildren().OfType<FrameworkElement>())
      {
        c.SizeChanged += new SizeChangedEventHandler(column_SizeChanged);
      }
    }

    void column_SizeChanged(object sender, SizeChangedEventArgs e)
    {
      timer.Stop();
      timer.Start();
    }

    DispatcherTimer timer;

    void fixDataGridRowsHeight()
    {
      datagrid.RowHeight = 0;
      datagrid.UpdateLayout();
      datagrid.RowHeight = double.NaN;
      datagrid.UpdateLayout();
    }

    private void ReorderBehavior_Reordered(object sender, ReorderingEventArgs e)
    {
      var task = (TaskVM)e.DraggingElement.DataContext;
      var taskState = (TaskState)CellToTaskStateConverer.Instance.Convert(e.NewPanel.VisualParent<DataGridCell>(), null, null, null);
      task.State = taskState;

      int index = 0;
      foreach (var c in e.NewPanel.Children.OfType<FrameworkElement>())
      {
        ((TaskVM)c.DataContext).OrderNumber = index++;
      }
      timer.Start();
    }

    private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
      if (e.ClickCount == 2)
      {
        new EditTask { DataContext = ((FrameworkElement)sender).DataContext }.Show();
      }
    }

    private void AddTask_Click(object sender, RoutedEventArgs e)
    {
      var element = ((FrameworkElement)sender);
      StoryVM story = element.DataContext as StoryVM;
      TaskVM task = new TaskVM
      {
        TeamMember = ((MainVM)DataContext).CurrentUser,
        Name = "New Task",
        EstimatedTime = "1",
        OrderNumber = 0,
        State = TaskState.ToDo,
        Background = new Color { R = 53, G = 149, B = 184, A=255 }
      };
      story.Tasks.Insert(0, task);


      var panel = datagrid.Columns[1].GetCellContent(story)
                  .DescendantsAndSelf<Panel>()
                  .FirstOrDefault(p => Interaction.GetBehaviors(p).OfType<ChildrenGeneratorBehavior>().FirstOrDefault() != null);
      var item = Interaction.GetBehaviors(panel).OfType<ChildrenGeneratorBehavior>().FirstOrDefault().GenerateItem(task);
      panel.Children.Insert(0, item);
    }

    private void RemoveTask_Click(object sender, RoutedEventArgs e)
    {
      var task = (TaskVM)(sender as FrameworkElement).DataContext;
      var item = datagrid.Descendants<FrameworkElement>().Where(f => f.Tag as string == "task" && f.DataContext == task).FirstOrDefault();
      var parent = item.VisualParent<Panel>();
      parent.Children.Remove(item);
      (parent.DataContext as StoryVM).Tasks.Remove(task);
    }

    private void EditTask_Click(object sender, RoutedEventArgs e)
    {
      var task = (TaskVM)(sender as FrameworkElement).DataContext;
      new EditTask { DataContext = task }.Show();
    }

  }
}
